home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1996 March / EnigmA AMIGA RUN 05 (1996)(G.R. Edizioni)(IT)[!][issue 1996-03][Skylink CD IV].iso / earcd / program / ixemlsrc.lha / ixemul / library / ix_open.c < prev    next >
C/C++ Source or Header  |  1995-12-23  |  8KB  |  229 lines

  1. /*
  2.  *  This file is part of ixemul.library for the Amiga.
  3.  *  Copyright (C) 1991, 1992  Markus M. Wild
  4.  *  Portions Copyright (C) 1994 Rafael W. Luebbert
  5.  *
  6.  *  This library is free software; you can redistribute it and/or
  7.  *  modify it under the terms of the GNU Library General Public
  8.  *  License as published by the Free Software Foundation; either
  9.  *  version 2 of the License, or (at your option) any later version.
  10.  *
  11.  *  This library is distributed in the hope that it will be useful,
  12.  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
  13.  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14.  *  Library General Public License for more details.
  15.  *
  16.  *  You should have received a copy of the GNU Library General Public
  17.  *  License along with this library; if not, write to the Free
  18.  *  Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  19.  *
  20.  *  $Id: ix_open.c,v 1.7 1994/06/19 15:13:03 rluebbert Exp $
  21.  *
  22.  *  $Log: ix_open.c,v $
  23.  *  Revision 1.7  1994/06/19  15:13:03  rluebbert
  24.  *  *** empty log message ***
  25.  *
  26.  *  Revision 1.5  1992/10/20  16:20:56  mwild
  27.  *  initialize malloc-region pointer (necessary after vfork-change)
  28.  *
  29.  *  Revision 1.4  1992/08/09  20:53:36  amiga
  30.  *  clean up
  31.  *
  32.  *  Revision 1.3  1992/05/20  01:31:30  mwild
  33.  *  move atexit(_cleanup) into ix_get_vars2 after stdio initialisation
  34.  *
  35.  * Revision 1.2  1992/05/18  12:20:27  mwild
  36.  * change async mp to be global
  37.  *
  38.  * Revision 1.1  1992/05/14  19:55:40  mwild
  39.  * Initial revision
  40.  *
  41.  */
  42.  
  43. #define KERNEL
  44. #include "ixemul.h"
  45. #include "kprintf.h"
  46.  
  47. #include <hardware/intbits.h>
  48.  
  49. #include <exec/memory.h>
  50. #include <string.h>
  51.  
  52. extern void launch_glue (), switch_glue ();
  53. extern void trap_20 ();
  54. extern void trap_00 ();
  55. extern int ix_timer();
  56.  
  57. struct ixemul_base *
  58. ix_open (struct ixemul_base *ixbase)
  59. {
  60.   /* here we must initialize our `user' structure */
  61.   struct user *ix_u;
  62.   /* an errno for those that later don't set it in ix_startup() */
  63.   static int default_errno;
  64.   struct MsgPort *debugger;
  65.   APTR handler;
  66.   struct Task *me;
  67.  
  68.   me = SysBase->ThisTask;
  69.  
  70.   ix_u = (struct user *) kmalloc (sizeof (struct user));
  71.   if (ix_u)  
  72.     {
  73.       /* bzero is safe, ie. doesn't need to reference struct user */
  74.       bzero (ix_u, sizeof (struct user));
  75.  
  76.       /* remember old state */
  77.       ix_u->u_otask_flags = me->tc_Flags;
  78.       ix_u->u_olaunch     = me->tc_Launch;
  79.       ix_u->u_oswitch     = me->tc_Switch;
  80.       ix_u->u_otrap_code  = me->tc_TrapCode;
  81.       ix_u->u_otrap_data  = me->tc_TrapData;
  82.     
  83.       NewList ((struct List *) &ix_u->u_md.md_list);
  84.  
  85.       ix_u->u_mdp           = &ix_u->u_md;
  86.  
  87.       KPRINTF (("ix_open: ix_u = $%lx, ix_open @$lx\n", ix_u, ix_open));
  88.  
  89.       me->tc_TrapData  = (APTR)ix_u;
  90.  
  91.       if (betterthan68000())
  92.     handler = trap_20;
  93.       else
  94.     handler = trap_00;
  95.  
  96.       Forbid ();
  97.  
  98.       /* Give an external debugger a chance before we overwrite the
  99.          tasks traphandler.  If a debugger has put up a public port,
  100.          we call it, and it then might choose to forward some traps
  101.          to our traphandler, if it so chooses.
  102.          If the debugger will handle our traps, it returns a non-zero
  103.          value, if it doesn't want to handler our traps, it returns zero.  */
  104.  
  105.       debugger = FindPort ("debugger_traphandler_insert");
  106.       if (debugger && ((int (*)(APTR))debugger->mp_SigTask) (handler))
  107.         {
  108.           /* A debugger offered to serve our traps and chose to do it. 
  109.              It has got the address of our own trap handler as well,
  110.              in case it would like to forward a trap to us.  */
  111.         }
  112.       else
  113.         {
  114.           /* No debugger is interested, so we handle our own traps.  */
  115.           me->tc_TrapCode  = handler;
  116.         }
  117.       Permit ();
  118.  
  119.       /* setup the p_sigignore mask correctly */
  120.       siginit (ix_u);
  121.       me->tc_SigRecvd &= 0x0fff;
  122.  
  123.       /* this library is a replacement for any c-library, thus we should be
  124.        * started at the START of a program, and out of 16 available signals 
  125.        * this call simply has to succeed... I know I'm a lazy guy ;-) */
  126.       ix_u->u_sleep_sig   = AllocSignal (-1);
  127.  
  128.       /* network related functions are only enabled if InetBase is != 0 */
  129.       ix_u->u_InetBase = OpenLibrary ("inet.library", 5);
  130.       if (ix_u->u_InetBase)
  131.     {
  132.           ix_u->u_sigurg      = AllocSignal (-1);
  133.           ix_u->u_sigio       = AllocSignal (-1);
  134.         }
  135.  
  136.       me->tc_Launch    = launch_glue;
  137.       me->tc_Switch    = switch_glue;
  138.       me->tc_Flags    |= TF_LAUNCH | TF_SWITCH;
  139.       ix_u->u_itimerint.is_Node.ln_Type = NT_INTERRUPT;
  140.       ix_u->u_itimerint.is_Node.ln_Name = me->tc_Node.ln_Name;
  141.       ix_u->u_itimerint.is_Node.ln_Pri  = 1;
  142.       ix_u->u_itimerint.is_Data         = (APTR) me;
  143.       ix_u->u_itimerint.is_Code            = (APTR) ix_timer;
  144.  
  145.  
  146.       AddIntServer (INTB_VERTB, &ix_u->u_itimerint);
  147.  
  148.       ix_u->u_trace_flags = 1;
  149.       ix_u->u_ixbase = ixbase;
  150.       ix_u->u_errno = &default_errno;
  151.       ix_u->u_sync_mp = (struct MsgPort *) syscall (SYS_CreatePort, 0, 0);
  152.       
  153.       /* the CD storage. since 0 is a valid value for a lock, we use -1 */
  154.       ix_u->u_startup_cd = (BPTR)-1;
  155.  
  156.       /* support for subprocesses a la Unix */
  157.  
  158.       /* each process starts out to be in its own process group. vfork()
  159.        * scribbles over this to inherit the parents process group instead */
  160.       ix_u->p_pgrp = (int) me;
  161.       ix_u->p_pptr = (struct Process *) 1;        /* hi init ;-)) */
  162.       ix_u->p_cptr =
  163.         ix_u->p_osptr =
  164.           ix_u->p_ysptr = 0;            /* no children to start with */
  165.       ix_u->p_vfork_msg = 0;
  166.       ix_u->p_zombie_sig = AllocSignal (-1);
  167.       ix_u->u_rand_next = 1;
  168.       NewList ((struct List *) &ix_u->p_zombies);
  169.  
  170.       if (ix_u->u_sync_mp)
  171.         {
  172.           ix_u->u_time_req = (struct timerequest *)
  173.         syscall (SYS_CreateExtIO, ix_u->u_sync_mp, sizeof (struct timerequest));
  174.       
  175.       if (ix_u->u_time_req)
  176.         {
  177.           if (!OpenDevice (TIMERNAME, UNIT_MICROHZ,
  178.                          (struct IORequest *) ix_u->u_time_req, 0))
  179.             {
  180.           syscall (SYS_gettimeofday, &ix_u->u_start, 0);
  181.  
  182.           /* have to mask out ALL signals until ix_startup has had a
  183.            * chance to setup its exit jmp_buf. If not, _longjmp will
  184.            * generate a longjmp-botch using a not initialized jmpbuf! */
  185.           syscall (SYS_sigsetmask, ~0);
  186.  
  187.           /* if enabled, set the red zone pointer for stack watch */
  188.           if (ixbase->ix_red_zone_size)
  189.             {
  190.               struct Process *mep = (struct Process *) me;
  191.               struct CommandLineInterface *CLI = BTOCPTR (mep->pr_CLI);
  192.               u_int stack_size = CLI ? CLI->cli_DefaultStack * 4 : mep->pr_StackSize;
  193.  
  194.               /* I guess the above approach to find the correct stack
  195.                  size will work most of the time. But using tc_Lower
  196.                  as lower bound would probably not work. Thus I'm using
  197.                  the current stack value, not the unknown `real' top stack
  198.              as top and subtract the stack_size to get to the bottom */
  199.  
  200.               if (stack_size > ixbase->ix_red_zone_size)
  201.                 ix_u->u_red_zone = (void *)(get_sp () - stack_size 
  202.                              + ixbase->ix_red_zone_size);
  203.             }
  204.           return ixbase;
  205.         }
  206.           /* couldn't open the timer device */
  207.           syscall (SYS_DeleteExtIO, ix_u->u_time_req);
  208.         }
  209.         }
  210.  
  211.       if (ix_u->u_sync_mp)
  212.         syscall (SYS_DeletePort, ix_u->u_sync_mp);
  213.  
  214.       RemIntServer (INTB_VERTB, &ix_u->u_itimerint);
  215.       me->tc_Flags    = ix_u->u_otask_flags;
  216.       me->tc_Launch   = ix_u->u_olaunch;
  217.       FreeSignal (ix_u->u_sleep_sig);
  218.  
  219.       /* all_free() MUST come before we remove the pointer to u */
  220.       all_free ();
  221.       me->tc_TrapCode = ix_u->u_otrap_code;
  222.       me->tc_TrapData = ix_u->u_otrap_data;
  223.  
  224.       kfree (ix_u);
  225.     }
  226.  
  227.   return 0;
  228. }
  229.